package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"time"
)

//利用管道实现 信号量
func main() {
	//停车场默认有2个空闲车位
	parkingLot := make(parkingLot, 2)
	for i := 0; i < cap(parkingLot); i++ {
		parkingLot <- parkingSpace(i)
	}

	//模拟每秒都有客人光顾，共1000人
	for i := 1; i < 1000; i++ {
		go parkingLot.ServeGuest(i)
		time.Sleep(1 * time.Second)
	}

}

func (lot parkingLot) ServeGuest(guestNo int) {
	fmt.Println("客人" + strconv.Itoa(guestNo) + "到来，等待空闲车位")
	//来一个客人，就消耗一个停车位
	parkingSpace := <-lot
	fmt.Println("客人" + strconv.Itoa(guestNo) + "使用空闲车位")
	defer func() {
		//客人走时，空闲一个停车位
		lot <- parkingSpace
		fmt.Println("客人" + strconv.Itoa(guestNo) + "离开，停车位空出一个")
	}()
	//模拟客人待的时长
	//[0,2)
	rnd := 2 + rand.Int63n(9) //至少待2秒，最多10秒
	fmt.Println("客人" + strconv.Itoa(guestNo) + "等待" + strconv.Itoa(int(rnd)) + "秒")
	time.Sleep(time.Duration(rnd) * time.Second)

}

//车位
type parkingSpace int

//停车场
type parkingLot chan parkingSpace
